#!/usr/bin/python

from .. import conv, function, metric, silk

class Error(silk.Error):
  """Used to signal errors during trace formatting."""
  pass

def format(trace, indent=0):
  string = ''

  lines = []
  for obj in trace:
    t = type(obj['obj'])
    if issubclass(t, function.Function):
      lines.append(format_func(obj))
    elif issubclass(t, function.Param):
      lines.append(format_param(obj))
    elif issubclass(t, metric.MetricAggregation):
      lines.append(format_aggr(obj))
    else:
      raise Error('Unknown object type "%s" encountered in trace' % t)

  return indent_lines(lines, indent)

def indent_lines(lines, indent):
  string = ',\n'.join(lines) + '\n'
  lines = string.split('\n')
  lines = [' ' * indent + line for line in lines]
  lines[-1] = lines[-1][indent:]
  return '\n'.join(lines)

def format_func(func):
  return '%s(\n%s) = %s [W:%s O:%s D:%s]' % (
    func['obj'].identifier, format(func['params'], 2), func['value'],
    func.get('weight', '-'), func.get('optional', '-'),
    func.get('default', '-')
  )

def format_aggr(aggr):
  return '%s(\n%s) = %s [W:%s O:%s D:%s]' % (
    aggr['obj'].aggr_type, format(aggr['metrics'], 2), aggr['value'],
    aggr.get('weight', '-'), aggr.get('optional', '-'),
    aggr.get('default', '-')
  )

def format_param(param):
  if 'path' in param:
    value = 'path("%s")' % str(param['path'].path)
  else:
    value = '"%s"' % conv.string(param['value'][0])

  return '%s=%s' % (param['name'], value)
